package com.evil.common.core.util;

import cn.hutool.core.collection.CollectionUtil;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 层级分类
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
public class ClassifyUtil {

    /**
     * 转换set
     *
     * @param list  list
     * @param trans trans
     * @param <T>   T
     * @param <V>   V
     * @return List
     */
    public static <T, V> Set<V> transTreeSetT(Collection<T> list, Function<T, V> trans, Function<T, Collection<T>> getChildren) {
        Set<V> set = new HashSet<>();
        list.forEach(l -> {
            set.add(trans.apply(l));
            Collection<T> children = getChildren.apply(l);
            // 非空递归
            if (CollectionUtil.isNotEmpty(children)) {
                set.addAll(ClassifyUtil.transTreeSetT(children, trans, getChildren));
            }
        });
        return set;
    }

    public static <T, U> List<T> classify(List<T> list, Function<T, U> getId, Function<T, U> getParentId, Comparator<T> comparator, BiConsumer<T, List<T>> setChildren, U root) {
        Map<U, List<T>> levelMap = list.stream().sorted(comparator).collect(Collectors.groupingBy(getParentId));
        Map<U, T> map = StreamUtil.toOrderlyMapFK(list, e -> !getId.apply(e).equals(root), getId);
        for (Map.Entry<U, List<T>> entry : levelMap.entrySet()) {
            if (map.containsKey(entry.getKey())) {
                setChildren.accept(map.get(entry.getKey()), entry.getValue());
            }
        }
        return levelMap.getOrDefault(root, new ArrayList<>());
    }
}
